package com.netease.nim.demo.session.activity;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.netease.nim.demo.base.YXBaseActivity;
import com.netease.nim.demo.common.adapter.TAdapterDelegate;
import com.netease.nim.demo.common.adapter.TViewHolder;
import com.netease.nim.demo.common.ui.listview.AutoRefreshListView;
import com.netease.nim.demo.common.ui.listview.ListViewUtil;
import com.netease.nim.demo.common.ui.listview.MessageListView;
import com.netease.nim.demo.contact.cache.ContactDataCache;
import com.netease.nim.demo.contact.cache.TeamDataCache;
import com.netease.nim.demo.session.adapter.MsgAdapter;
import com.netease.nim.demo.session.model.MsgListItem;
import com.netease.nim.demo.session.viewholder.MsgViewHolder;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.SystemMessageService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.AttachmentProgress;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.shwread.android.qysw10000204.R;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 漫游消息查询界面
 * <p/>
 * Created by huangjun on 2015/4/17.
 */
public class RoamingMessageActivity extends YXBaseActivity implements TAdapterDelegate,
        AutoRefreshListView.OnRefreshListener {

    private static final String EXTRA_DATA_ACCOUNT = "EXTRA_DATA_ACCOUNT";
    private static final String EXTRA_DATA_SESSION_TYPE = "EXTRA_DATA_SESSION_TYPE";

    protected static final int LOAD_MESSAGE_COUNT = 20;

    // context
    private SessionTypeEnum sessionType;
    private String account; // 对方账号

    // view
    private MessageListView listView;

    // adapter
    private MsgAdapter adapter;
    private List<MsgListItem> items = new ArrayList<MsgListItem>();
    private Set<String> itemIds = new HashSet<String>(); // uuid

    // state
    private IMMessage endMessage;
    private boolean firstLoad = true;
	private TextView tvTitle;
	private View btnBack;

    public static void start(Context context, String account, SessionTypeEnum sessionType) {
        Intent intent = new Intent();
        intent.putExtra(EXTRA_DATA_ACCOUNT, account);
        intent.putExtra(EXTRA_DATA_SESSION_TYPE, sessionType);
        intent.setClass(context, RoamingMessageActivity.class);
        context.startActivity(intent);
    }

    /**
     * *************** implements TAdapterDelegate ***************
     */
    @Override
    public int getViewTypeCount() {
        return adapter.getViewTypeCount();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Class<? extends TViewHolder> viewHolderAtPosition(int position) {
        return adapter.getViewHolderByType(items.get(position).getViewHolderType());
    }

    @Override
    public boolean enabled(int position) {
        return false;
    }


    /**
     * ************************* OnRefreshListener ***********************
     */
    @Override
    public void onRefreshFromStart() {
        loadRoamingMessages(LOAD_MESSAGE_COUNT, true); // load old data
    }

    @Override
    public void onRefreshFromEnd() {
    }


    /**
     * ***************************** life cycle *******************************
     */

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.roaming_message_activity);

        onParseIntent();

        initAdapter();
        initView();
        initData();

        loadRoamingMessages(LOAD_MESSAGE_COUNT, true); // load old data

        registerObserver(true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        registerObserver(false);
    }

    @Override
    protected void onResume() {
        super.onResume();

        NIMClient.getService(SystemMessageService.class).resetSystemMessageUnreadCount();
    }

    @Override
    protected void onStop() {
        super.onStop();

        NIMClient.getService(SystemMessageService.class).resetSystemMessageUnreadCount();
    }

    protected void onParseIntent() {
        account = getIntent().getStringExtra(EXTRA_DATA_ACCOUNT);
        sessionType = (SessionTypeEnum) getIntent().getSerializableExtra(EXTRA_DATA_SESSION_TYPE);
        if (sessionType == SessionTypeEnum.P2P) {
            setTitle(ContactDataCache.getInstance().getBuddyDisplayName(account));
        } else if (sessionType == SessionTypeEnum.Team) {
            setTitle(TeamDataCache.getInstance().getTeamName(account));
        }
    }

    private void initAdapter() {
        adapter = new MsgAdapter(this, items, this);
    }

    private void initView() {
    	tvTitle = (TextView) findViewById(R.id.common_header_name);
		tvTitle.setVisibility(View.VISIBLE);
		tvTitle.setText(getResources().getString(R.string.roaming_message_title));
		btnBack = (Button) findViewById(R.id.common_header_back);
		btnBack.setVisibility(View.VISIBLE);
		btnBack.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v) {
				finish();
			}
		});
        listView = (MessageListView) findViewById(R.id.messageListView);
        listView.requestDisallowInterceptTouchEvent(true);
        listView.setMode(AutoRefreshListView.Mode.START);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            listView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        }
        // listener
        listView.setOnRefreshListener(this);
        // adapter
        listView.setAdapter(adapter);
    }

    private void initData() {
        // 第一次查询时，构造一个空的消息记录作为锚点，时间填0即可。
        endMessage = MessageBuilder.createEmptyMessage(account, sessionType, 0);
    }

    private void registerObserver(boolean register) {
        NIMClient.getService(MsgServiceObserve.class).observeMsgStatus(messageStatusObserver, register);
        NIMClient.getService(MsgServiceObserve.class).observeAttachmentProgress(attachmentProgressObserver, register);
    }

    /**
     * 加载历史消息
     *
     * @param maxResultsCount 最多加载多少条
     * @param needOffset      是否合并到本地数据库
     */
    protected void loadRoamingMessages(final int maxResultsCount, final boolean needOffset) {
        // 使用已经查询到最老的一条消息记录作为锚点
        NIMClient.getService(MsgService.class).pullMessageHistory(endMessage, LOAD_MESSAGE_COUNT, false)
                .setCallback(new RequestCallback<List<IMMessage>>() {
                    @Override
                    public void onSuccess(List<IMMessage> msgList) {
                        boolean first = firstLoad;
                        firstLoad = false;
                        if (msgList != null) {
                            onMessageLoaded(msgList, first, maxResultsCount, needOffset);
                        }
                    }

                    @Override
                    public void onFailed(int code) {

                    }

                    @Override
                    public void onException(Throwable exception) {

                    }
                });
    }

    protected void onMessageLoaded(List<IMMessage> loadedMsgList, boolean first, int requestCount,
                                   boolean needOffset) {
        int count = loadedMsgList.size();
        if (loadedMsgList != null && loadedMsgList.size() > 0) {
            List<MsgListItem> addedItems = addOldMessages(loadedMsgList);
            count = addedItems.size();
            if (!addedItems.isEmpty()) {
                updateShowTimeItem(addedItems, null);

                // 下次查询的范围
                endMessage = loadedMsgList.get(loadedMsgList.size() - 1);
            } else {
                needOffset = false;
            }
        }

        // 第一次加载后显示底部
        if (first) {
            ListViewUtil.scrollToBottom(listView);
        }

        listView.onRefreshComplete(count, requestCount, needOffset);
    }

    private List<MsgListItem> addOldMessages(List<IMMessage> messages) {
        List<MsgListItem> addedItems = new ArrayList<MsgListItem>();

        for (IMMessage msg : messages) {
            if (duplicateFilter(msg)) {
                continue;
            }

            // 下载附件
            if (msg.getAttachment() != null) {
                NIMClient.getService(MsgService.class).downloadAttachment(msg, true);
            }

            MsgListItem item = new MsgListItem(msg);

            items.add(0, item);
            itemIds.add(msg.getUuid());
            addedItems.add(0, item);
        }

        if (!addedItems.isEmpty()) {
            refresh();
        }

        return addedItems;
    }

    // 去重
    private boolean duplicateFilter(final IMMessage msg) {
        if (itemIds.contains(msg.getUuid())) {
            return true;
        }

        return false;
    }

    private MsgListItem updateShowTimeItem(List<MsgListItem> items, MsgListItem lastShowTimeItem) {
        for (MsgListItem messageListItem : items) {
            if (setShowTimeFlag(messageListItem, lastShowTimeItem)) {
                lastShowTimeItem = messageListItem;
            }
        }

        return lastShowTimeItem;
    }

    private boolean setShowTimeFlag(MsgListItem item, MsgListItem lastShowTimeItem) {
        boolean update = false;

        IMMessage msg = item.getMessage();
        if (item.hideTimeAlways()) {
            item.needShowTime = false;
        } else {
            if (lastShowTimeItem == null) {
                item.needShowTime = true;
                update = true;
            } else {
                long time = lastShowTimeItem.getMessage().getTime();
                long now = msg.getTime();

                if (now - time < (long) (5 * 60 * 1000)) {
                    item.needShowTime = false;
                } else {
                    item.needShowTime = true;
                    update = true;
                }
            }
        }

        return update;
    }


    private void refresh() {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                adapter.notifyDataSetChanged();
            }
        });
    }

    private Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
        @Override
        public void onEvent(AttachmentProgress progress) {
            int index = getItemIndex(progress.getUuid());
            if (index >= 0 && index < items.size()) {
                MsgListItem item = items.get(index);
                item.progress = (float) progress.getTransferred() / (float) progress.getTotal();
                refreshViewHolderByIndex(index);
            }
        }
    };

    Observer<IMMessage> messageStatusObserver = new Observer<IMMessage>() {
        @Override
        public void onEvent(IMMessage message) {
            if (!message.getSessionId().equals(account)) {
                return;
            }

            int index = getItemIndex(message.getUuid());
            if (index >= 0 && index < items.size()) {
                MsgListItem item = items.get(index);
                item.getMessage().setStatus(message.getStatus());
                item.getMessage().setAttachStatus(message.getAttachStatus());
                refreshViewHolderByIndex(index);
            }
        }
    };

    private int getItemIndex(String uuid) {
        for (int i = 0; i < items.size(); i++) {
            MsgListItem item = items.get(i);
            if (TextUtils.equals(item.getMessage().getUuid(), uuid)) {
                return i;
            }
        }

        return -1;
    }

    private void refreshViewHolderByIndex(final int index) {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (index < 0) {
                    return;
                }

                Object tag = ListViewUtil.getViewHolderByIndex(listView, index);
                if (tag instanceof MsgViewHolder) {
                    MsgViewHolder viewHolder = (MsgViewHolder) tag;
                    viewHolder.refreshCurrentItem();
                }
            }
        });
    }
}
